var websocket = require("websocket");
var wxLogin = require("wxLogin");
cc.Class({ 

    extends: cc.Component,

    properties: {

        // 节点
        home: cc.Node,
        bg_1: cc.Node,
        bg_shade: cc.Node,
        // bg_2: cc.Node,
        gameReady: cc.Node,
        gamePlaying: cc.Node,
        gamePause: cc.Node,
        gameOver: cc.Node,
        gameTop: cc.Node,
        hreo: cc.Node,
        hreoRebirth: cc.Node,
        ad: cc.Node,
        gameLevel: cc.Node,

        // 模型
        bullet: cc.Prefab,
        spark: cc.Prefab,
        gold: cc.Prefab,
        enemy_1: cc.Prefab,
        enemy_2: cc.Prefab,
        enemy_3: cc.Prefab,
        skill: cc.Prefab,

        // 声效
        bgm: cc.AudioClip,
        hreoDieSound: cc.AudioClip,
        enemyDieSound: cc.AudioClip,
        hreoDie: cc.AudioClip,
    },


    onLoad () {

        // 连接服务器
        websocket.connect(); 

        if(cc.sys.platform == cc.sys.WECHAT_GAME){
          wxLogin.login()
        }

        //全局变量
        window.game = this

        // 开启碰撞检测系统
        cc.director.getCollisionManager().enabled = true

        this.playing = this.gamePlaying.getComponent('gamePlaying')
        this.top = this.gameTop.getComponent('gameTop')
        this.jHreo = this.hreo.getComponent('hreo')
        this.jHreoRebirth = this.hreoRebirth.getComponent('hreoRebirth')
        this.jGameLevel = this.gameLevel.getComponent('gameLevel')
        this.jGameOver = this.gameOver.getComponent('gameOver')

        this.setTouch()
        this.gameReady.active = true
        this.gamePlaying.active = false
        this.gamePlaying.zIndex = 3
        this.gamePause.active = false
        this.gamePause.zIndex = 3
        this.gameOver.active = false
        this.gameStatus = 0 // [ 0:ready 1:play 2:pause 3:over ]
        this.gameTime = 0  //游戏时间
        this.buttetTime = 0  //子弹创建时间


        this.isAttack = false      //是否开始攻击
        this.enemyTime = 0        
        this.enemyInterval = 120  //创建敌人时间间隔
        this.enemySpeed = 1       //敌人运行速度
        this.odds = [60, 90, 100] //敌机生成概率


        let enemyCount = 100
        this.enemy1Pool = new cc.NodePool()
        this.enemy2Pool = new cc.NodePool()
        this.enemy3Pool = new cc.NodePool()
        for (let i = 0; i < enemyCount; ++i) {
            let enemy1 = cc.instantiate(this.enemy_1); 
            this.enemy1Pool.put(enemy1); 
            let enemy2 = cc.instantiate(this.enemy_2); 
            this.enemy2Pool.put(enemy2); 
            let enemy3 = cc.instantiate(this.enemy_3); 
            this.enemy3Pool.put(enemy3); 
        }
        
        let bulletCount = 300
        this.bulletPool = new cc.NodePool()
        this.sparkPool = new cc.NodePool()
        for (let i = 0; i < bulletCount; ++i) {
            let bullet = cc.instantiate(this.bullet); 
            this.bulletPool.put(bullet); 
            let spark = cc.instantiate(this.spark); 
            this.sparkPool.put(spark); 
        }
    
        this.skillPool = new cc.NodePool()
        this.goldPool = new cc.NodePool();

        this.bgmId =  cc.audioEngine.play(this.bgm, true, 1);

        
    },


    //创建四叉树
    // createQuadtree(){
    //     //区域为整个屏幕
    //     let myTree = new Quadtree({
    //         x: -cc.winSize.width / 2,
    //         y: -cc.winSize.height / 2,
    //         width: cc.winSize.width / 2,
    //         height: cc.winSize.height / 2
    //     });

    //     //参数为元素的左下角坐标及其宽高
    //     myTree.insert({
    //         x: 200,
    //         y: 150,
    //         width: 20,
    //         height: 20
    //     });

    //     //参数为目标元素的左下角坐标及其宽高,返回值为碰撞候选元素数组
    //     let elements = myTree.retrieve({
    //         x: 150,
    //         y: 100,
    //         width: 20,
    //         height: 20
    //     });

    //     console.log("碰撞候选元素： "+ elements + "进行检测·······") 

    //     console.log("清除四叉树 myTree.clear();")
    //     myTree.clear()

    // },



    // 触摸事件
    setTouch(){
        //触摸开始
        this.node.on('touchstart', function (event) {
            
            if(this.gameStatus == 1){
                this.isAttack = true
                this.bg_shade.runAction(cc.fadeOut(0.5))
                this.enemySpeed = 100
            }

            if(this.gameStatus == 0){  
                this.home.active = false
                this.gameTop.active = false
                this.jGameLevel.moveOut()
                this.bg_1.active = true
                this.bg_shade.active = true

                this.gameReady.active = false
                this.gamePlaying.active = true
              
                this.gameStatus = 1
            }

        }, this);
       
      
        //触摸移动
        this.node.on('touchmove', function (event) {
            if(this.gameStatus == 1){
                var hreo_pos = this.hreo.getPosition()
                var move_pos = event.getDelta()
                var hreo_pos = cc.v2(hreo_pos.x + move_pos.x, hreo_pos.y + move_pos.y)
                if (hreo_pos.x < -270) hreo_pos.x = -270
                if (hreo_pos.x > 270)  hreo_pos.x = 270
                if (hreo_pos.y < -500) hreo_pos.y = -500
                if (hreo_pos.y > 500)  hreo_pos.y = 500
                this.hreo.setPosition(hreo_pos)
            }
        }, this);


        //触摸结束
        this.node.on('touchend', function (event) {
            this.isAttack = false
            this.bg_shade.runAction(cc.fadeIn(0.5))
            this.enemySpeed = 30
        }, this);

    },


    clickBtn(sender,str){
        //暂停
        if(str == 'stop'){
            this.gameStatus = 2
            this.gamePause.active = true
        }
        //继续
        else if (str == 'continue'){
            this.gameStatus = 1
            this.gamePause.active = false
        }
        //重新开始
        else if (str == 'restart'){
            this.gameStatus = 1
            this.gamePause.active = false
            this.gameOver.active = false
            this.clearBullet()
            this.clearAllRes()
            this.playing.init()
            this.gameTime = 0
            data.init()

            var js = this.hreo.getComponent("hreo")
            if(js){
                js.init()
                this.hreo.setPosition(cc.v2(0,-350))
            }
        }
        //主页
        else if (str == 'home'){
            // this.gameStatus = 0
            this.home.active = true
            this.bg_1.active = false
            this.gameTop.active = true
            this.gameLevel.active = true
            this.gameReady.active = true
            this.gamePlaying.active = false
            this.gamePause.active = false
            this.gameOver.active = false
            this.clearBullet()
            this.clearAllRes()
            this.playing.init()
            this.gameTime = 0
            
            this.jGameLevel.init()
            this.jHreo.init()
        }
    },




    //设置音效
    playHreoDieSound(){
        cc.audioEngine.play(this.hreoDieSound, false, 1);
    },
    playEnemyDieSound(){
        cc.audioEngine.play(this.enemyDieSound, false, 1);
    },
  

    //游戏结束
    gameEnd(){
        game.gameStatus = 3 
        this.gamePlaying.active = false
        this.gamePause.active = false
        this.bg_shade.active = false
        this.gameOver.active = true
    },




    /**
     * 对象池获取子弹
     */
    getBullet(ofset,type){
        let newBullet = null;
        if (this.bulletPool.size() > 0) {
            newBullet = this.bulletPool.get();
        } else {
            newBullet = cc.instantiate(this.bullet)
        }
        newBullet.parent = this.node
        var pos = this.hreo.getPosition()

        if(type == 0){
            newBullet.setPosition(cc.v2(pos.x, pos.y + this.hreo.height/2+5))
        }

        if(type == 1){
            pos.y += 50;
            newBullet.setPosition(pos);
            let js = newBullet.getComponent('bullet');
            js.setSecondPos(cc.v2(pos.x + ofset,  pos.y));
        }
        
        if(data.buttetType == 0){
            utils.setSpriteAtlas(newBullet, 'plist/gun', 'd0_1')
        } else {
            utils.setSpriteAtlas(newBullet, 'plist/gun', 'd0_2')
        }
        
        
    },

    
    //创建子弹
    createBullet(count){
        if(count <= 1){
            this.getBullet(0,0)
        }else{
           // 多个子弹时的位置显示
           let left = 1; // 左边显示几个子弹
           let right = 1;// 右边显示几个子弹
           let imgSize = 20; // 子弹宽度
           for (let i = 0; i < count; i++) { 
                let ofset = 0; //子弹位置
                //子弹为奇数时，设置第一个为0
                if(count % 2 != 0){  
                    if(i == 0) {
                        ofset = 0 
                    }else{
                        if (i % 2) {  
                            ofset = -imgSize * left 
                            left++;
                        } else {  
                            ofset = imgSize * right 
                            right++;
                        }
                    }
                }
                // 子弹为偶数时
                else{
                    if (i % 2) {  
                        ofset = -imgSize * left //-30 -60 -90
                        ofset += imgSize / 2;  //-15 -45 -75
                        left++;
                    } else {  
                        ofset = imgSize * right 
                        ofset -= imgSize / 2;  
                        right++;
                    }
                }
                this.getBullet(ofset,1)
                
           }

        }

    },
    

    
    //子弹对象池回收
    delBullet: function (enemy) {
        this.bulletPool.put(enemy);
    },


    //移除所有子弹
    clearBullet(){
        var children = this.node.children
        for (let i = children.length - 1; i>=0; i--) {
            var jb = children[i].getComponent('bullet');
            if(jb){
                this.delBullet(children[i])
            }
        }
    },


     /**
      * 对象池获取撞击火花
      * @param {*} enemyNode 
      */
     getSpark(enemyNode){
        let newfab = null;
        if (this.sparkPool.size() > 0) {
            newfab = this.sparkPool.get();
        } else { 
            newfab = cc.instantiate(this.spark)
        }
        newfab.parent = this.node
        var pos = enemyNode.getPosition();
        newfab.setPosition(cc.v2(pos.x , pos.y - enemyNode.height/4))
      
        var js = newfab.getComponent('spark')
        if(js){
            js.die()
        }
    },

    
    /**
     * 对象池获取道具
     */
    createProp(enemyNode, type){
        let newfab = null
        if (this.skillPool.size() > 0) {
            newfab = this.skillPool.get();
        }else{
            newfab = cc.instantiate(this.skill)
        }
        newfab.parent = this.node
        var pos = enemyNode.getPosition();
        newfab.getComponent(cc.Collider).tag = type
        newfab.getComponent('skill').flag.string = type;
        newfab.setPosition(cc.v2(pos.x, pos.y))
    },


    addProp(enemyNode){
        var num = Math.random() * 100 //生成道具概率
        if(num > 90){  
            var type = parseInt(1000 + Math.random() * 3 + 1) //生成哪种道具
            cc.log("生成道具：" + type)
            this.createProp(enemyNode, type)
        }
    },



    /**
     * 对象池创建敌人
     * @param {*} enemyType  敌人类型
     */
    creatEnemy(enemyType){
        let newEnemy = null
        var str = ''
        var posEnemy = cc.v2(0, 650)
        //生成敌人一
        if(enemyType == 1){
            if (this.enemy1Pool.size() > 0) {
                newEnemy = this.enemy1Pool.get();
            } else { 
                newEnemy = cc.instantiate(this.enemy_1)
            }
            str = 'enemy_1'
            posEnemy.x = -290 + Math.random() * 580
            posEnemy.y = 600 + Math.random() * 100
        }

        //生成敌人二
        else if(enemyType == 2){
            if (this.enemy2Pool.size() > 0) {
                newEnemy = this.enemy2Pool.get();
            } else { 
                newEnemy = cc.instantiate(this.enemy_2)
            }
            str = 'enemy_2'
            posEnemy.x = -280 + Math.random() * 560
            posEnemy.y = 630 + Math.random() * 100
        }

         //生成敌人三
         else if(enemyType == 3){
            if (this.enemy3Pool.size() > 0) {
                newEnemy = this.enemy3Pool.get();
            } else { 
                newEnemy = cc.instantiate(this.enemy_3)
            }
            str = 'enemy_3'
            posEnemy.x = -230 + Math.random() * 460
            posEnemy.y = 700 + Math.random() * 100
        }

        newEnemy.parent = this.node
        var js = newEnemy.getComponent(str)
        //运行速度
        var speed = Math.random() * 50 + 1
        if(js) js.init(speed)
        newEnemy.setPosition(posEnemy)
    },

    
    //回到主页移除所有组件
    clearAllRes(){
        var children = this.node.children
        for (let i = children.length - 1; i>=0; i--) {
            if(children[i].getComponent('enemy_1')){
                this.delPrefab(children[i], 1)
            }
            if(children[i].getComponent('enemy_2')){
                this.delPrefab(children[i], 2)
            }
            if(children[i].getComponent('enemy_3')){
                this.delPrefab(children[i], 3)
            }
            if(children[i].getComponent('skill')){
                this.delPrefab(children[i], 1001)
            }
        }

        this.playing.skillProgress.getComponent("skillProgress").clearProgress()
    
    },

    
    //对象池回收
    delPrefab(fab, fabType) {
        if(fabType == 0)this.sparkPool.put(fab);  //回收火花
        if(fabType == 1)this.enemy1Pool.put(fab); //回收敌人1
        if(fabType == 2)this.enemy2Pool.put(fab); //回收敌人2
        if(fabType == 3)this.enemy3Pool.put(fab); //回收敌人3
        if(fabType == 1001 || fabType == 1002 || fabType == 1003)this.skillPool.put(fab);  //回收道具
    },


   

   
    /**
     * 创建金币的动画
     * @param {*} srcPos  开始位置,
     * @param {*} dstPos  目标位置
     * @param {*} srcNode 顶部的金币node
     * @param {*} radius  圆半径
     * @param {*} goldCount  切分多少块,多少个金币
     * @param {*} addGold 需要增加多少金币
     * @param {*} callBack 动画结束回调
     */
    createGoldAnim(srcPos,dstPos,srcNode,radius,goldCount,addGold,callBack){
   
        var array = utils.getPoint(radius,srcPos.x,srcPos.y,goldCount);
        var nodeArray = new Array();
        array.forEach(n =>{
            var gold = this.createGold(this.node); //创建金币
            var randPos = cc.v2(n.x + utils.random(0,50), n.y + utils.random(0,50));
            gold.setPosition(srcPos);
            nodeArray.push({gold,randPos});
        })
        // 根据两点的距离排序 距离近的先到目标点
        nodeArray.sort(
            function(a,b){
                var disa = utils.distance(a.randPos,dstPos)
                var disb = utils.distance(b.randPos,dstPos)
                return disa - disb
            }
        );

        var notPlay = false; // 是否金币动画放大播放结束
        var targetGoldNode = srcNode; // 获取顶部的金币node

        nodeArray.forEach((v, i) => {
            let seq = cc.sequence(
                cc.moveTo(0.3, v.randPos),
                cc.delayTime(i * 0.02), // 距离越远的越靠后运动
                cc.moveTo(0.3, dstPos),
                cc.callFunc((v) => {
                    if (!notPlay) {
                        notPlay = true;
                        let seq = cc.sequence(
                            cc.scaleTo(0.1, 1.5, 1.5),
                            cc.scaleTo(0.1, 1, 1),
                            cc.callFunc(() => notPlay = false) // 金币动画放大结束
                        )
                        targetGoldNode.runAction(seq);
                    }
                    if (i == nodeArray.length - 1) {
                        if (callBack != null) callBack(addGold);
                    }
                    this.onGoldKilled(v)
                })
            )
            v.gold.runAction(seq);

        })
    },

    createGold: function (parentNode) {
        let enemy = null;
        if (this.goldPool.size() > 0) {
            enemy = this.goldPool.get();
        } else {
            enemy = cc.instantiate(this.gold);
        }
        enemy.parent = parentNode;
        return enemy;
    },

    onGoldKilled: function (gold) {
        this.goldPool.put(gold); 
    },


    
    update (dt) {

        //创造子弹
        this.buttetTime++
        if(this.buttetTime == 5){
            this.buttetTime = 0
            if(this.gameStatus == 1 && this.isAttack){
                this.createBullet(data.bulletNum)
            }
        }


        /**
         * 【游戏规则】
         */
        var enemyCount = 5; //默认生成敌机数量
        if(this.gameStatus == 1 && this.isAttack){
            this.gameTime++
            if(this.gameTime % 300 == 0){

                //1.随着时间生成的敌机越来越多
                enemyCount += Math.round(this.gameTime / 300)
                if(enemyCount > 15){
                    enemyCount = 15
                }

                //2.随着时间生成的敌机机率改变
                this.odds[0] = this.odds[0] - 2
                if(this.odds[0] < 40) this.odds[0] = 40
                this.odds[1] = this.odds[1] - 1
                if(this.odds[1] < 75) this.odds[1] = 75

            }
         }
         
     
        //创造敌人
        if(this.gameStatus == 1){ 
            this.enemyTime++
            if(this.enemyTime == this.enemyInterval){
                this.enemyTime = 0
                var enemyNum = Math.round(Math.random() * enemyCount + 1)  //随机生成数量 (1 至 enemyCount)
                for (let i = 0; i < enemyNum; i++) {
                    var num = Math.random() * 100 //生成概率
                    if (num < this.odds[0]){   
                        this.creatEnemy(1)
                    }else if (num < this.odds[1]){
                        this.creatEnemy(2)
                    }else if (num < this.odds[2]){
                        this.creatEnemy(3)
                    }
                }
                
            }
        }

    },
});
